package com.xunshibao.core.security;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;

public class SecurityAnnotationHandlerMapping extends DefaultAnnotationHandlerMapping {
    @Override
    protected HandlerExecutionChain getHandlerExecutionChain(Object handler,HttpServletRequest request){
        HandlerExecutionChain chain = super.getHandlerExecutionChain(handler,request);
        List<HandlerInterceptor> interceptors = detectSecurityInterceptors(chain.getHandler().getClass());
        if(!interceptors.isEmpty()) {
        	chain.addInterceptor(interceptors.get(0));
        }
        return chain;
    }

	private List<HandlerInterceptor> detectSecurityInterceptors(
			Class<?> handlerType) {
		final List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>(1);
		ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
			
			@Override
			public void doWith(Method method) throws IllegalArgumentException,
					IllegalAccessException {
				Security security = AnnotationUtils.findAnnotation(method, Security.class);
				if(security != null) {
					interceptors.add(getApplicationContext().getBean(SecurityInterceptor.class));
				}
			}
		}, ReflectionUtils.USER_DECLARED_METHODS);
		return interceptors;
	}
}
